\chapter{Novas Funcionalidades} \label{howTo}

Dentre as várias características de um software bem projetado, pode-se ressaltar que uma das desejadas é permitir facilmente a inclusão de novas funcionalidades. Para isso elabora-se um bom design do mesmo, bem como uma boa documentação. Com esse intuito aqui será apresentado um pequeno guia que serve de auxílio para inclusão de novas funcionalidades, bem como para um melhor entendimento do sistema.

\section{Adicionando uma função}

\subsection{Considerações Iniciais}

Inicialmente serão destacados alguns esclarecimentos básicos a respeito da organização do código fonte:

\begin{enumerate}
 \item Em relação a interface gráfica, o módulo principal que organiza os dados de interface gráfica da calculadora, incluindo a disposição de botões, é o CalcGui. Além desse, existem módulos que lidam com a tabela de amortização (calcTableDialog), com a tabela de \textit{recall} (recallViewDialog) e com a tabela de \textit{store} (storeViewDialog). 

\item Existe um componente que representa um botão (calcButton). Para cada botão pode-se adicionar até 3 textos de funções: uma na parte superior, um na parte inferior e um na parte central.

\item O \textit{controller} (calcController) captura todos os eventos de teclas pressionadas. A identificação das teclas se dá considerando o texto da parte central do botão 
(que representa a função principal de cada tecla). Em seguida o \textit{controller} chama uma ação correspondente no \textit{model} (calcModel).

\item O calcModel é a lógica de negócio do sistema. Esse módulo guarda o estado da calculadora (opções de arredondamento, se as teclas especiais f ou g estão pressionadas, etc) e conhece a pilha (calcStack), os demais registradores (calcRegs) e as funções da biblioteca financeira (pyFinancialLibrary).

\item O calcModel oferece publicamente funções que casam com as funções tidas como principais de cada botão (a funcão cujo texto fica no meio do botão). Dado que o calcModel conhece o estado da calculadora, em cada uma dessas chamadas verifica-se que função da biblioteca usar analisando, por exemplo, se o usuário selecionou os botões F ou G.

\item Na ligação da lógica de negócio, da interface gráfica e do controlador foi utilizado o modelo MVC \cite {mvc}. Os módulos da interface gráfica atuam como \textit{Observers} da lógica de negócio e assim são ativados pela mesma quando necessários. O model tem vários \textit{listeners} para eventos como: modificação do valor da tela, modificação da pilha, etc. A ativação de cada um desses \textit{listeners} ocorre ao final de cada função do model, bem como a análise de outras ações necessárias como, por exemplo desativar a seleção de F ou G feita pelo usuário.
% ; avisar listeners sobre alterações na pilha, registradores financeiros, etc, 
% dependendo do que a função faça; alertar a interface sobre modificação na tela, no estado dos botões ou sobre 
% a necessidade de mostrar a tabela de amortização, de recall ou de store.

\item Os dados fornecidos de volta aos \textit{listeners} estão sempre no tipo \textit{Decimal}, que é o tipo trabalhado pela calculadora de modo a alcançar alta precisão. Cada módulo da GUI formata esses dados como queira, fazendo uso das funções de formatacão presentes no módulo calcFormatUtil.

\end{enumerate}

Um complemento do que foi exposto aqui pode ser analisado avaliando-se os diagramas de classes presentes no Apêndice \ref{DiagramaClasses}.

\subsection{Exemplo de Adição de Função}

% Agora, como exemplo, irá se utilizar a implementação de uma nova forma de divisão em que ao invés de se dividir o 
% registrador Y pelo X, irá se dividir X por Y. Através desse exemplo, pretende-se abordar todo o passo-a-passo para se 
% implementar uma nova funcionalidade.
De modo a esclarecer melhor os pontos acima levantados, será simulada a implementação de uma nova funcionalidade na calculadora. Como exemplo, tem-se a adição de uma nova forma de divisão em que ao invés de se dividir o registrador Y pelo X, irá se dividir X por Y. 
Através desse exemplo, pretende-se abordar o passo-a-passo para se implementar uma nova funcionalidade no sistema em questão, considerando o caso simples de adição de uma função como principal em um dado botão.

Primeiramente é preciso escolher um botão do teclado da GUI que esteja livre para receber a nova função, ou ainda substituir uma função já alocada a algum botão. No método \begin{verbatim} __createKeyboardLayout \end{verbatim} do módulo calcGui é feita a adição de botões na tela. Nesse método deve-se escolher uma posição e adicionar o novo botão através do comando \begin{verbatim}self.__addGridButton(grid, "INV /", 1, 5)\end{verbatim}.

Em seguida, deve-se criar a ação a ser disparado no clique do botão. Para isso adiciona-se uma nova verificação do label central do botão pressionado no método \textbf{keyboardButtonClicked(self, text)} do \textit{controller}. Um exemplo pode ser observado no trecho de código \ref{else}: 

\lstinputlisting[language=Python, label=else, caption={Teste no controller}]{else.py}
% \begin{verbatim}
% 	elif text == "INV /":
%  		self.__model.invDiv()
% \end{verbatim}

No \textit{model} deve-se criar a função chamada no \textit{controller}, conforme visto acima. Na nova função do \textit{model} implementa-se a funcionalidade considerando o estado dos botões 
F e G, os valores dos registradores, o estado da calculadora e as funções disponíveis na biblioteca de funções (pyFinancialLibrary). 

Com o resultado da divisão em mãos, altera-se o valor de algum(ns) dos registradores conforme necessário. Conforme dito acima, ao final de cada função deve-se, se necessário, desativar as teclas F e G, alterar a posição de entrada de decimais, e conforme o que for modificado (tela, pilha, registradores financeiros, etc) avisar aos devidos \textit{listeners} os novos valores que lhes são de interesse. 

Um ponto importante é também alterar o modo de entrada de dados da calculadora de acordo com a funcionalidade desejada. Existem basicamente três modos, explicitados na classe \textit{Mode}: \textit{Mode.SaveMode} (que na próxima entrada de dados devolve o valor 0.0 a tela e então inicia o processamento do que for entrado), \textit{Mode.OperationMode} (devolve o valor zero a tela, mas antes dá um enter na pilha) e \textit{Mode.EntryMode} (indicando que novos dígitos estão sendo entrados ao valor anterior da tela). 

Um exemplo de implementação da nova função de divisão no calcModel pode ser observado no trecho de código \ref{funcao}.

\lstinputlisting[language=Python, label=funcao, caption={Definição de Função no Model}]{funcao.py}


% \begin{verbatim}
% 
%     def invDiv(self):
%         if self.__isGPushed or self.__isFPushed:
%             self.__fireException("Function not yet implemented.")
%             self.__deactiveFandG()
%         else:
%             # "inv /"
%             try:
%                 result = self.__calcStack.getXReg() / self.__calcStack.getYReg()
%                 self.__calcStack.rollCounterClockWise()
%                 self.__calcStack[0] = result
%                 self.__calcStack[3] = self.__calcStack[2]
%         
%                 self.mode = Mode.OperationMode
%                 self.base = None
%                 self.dotActived = False
%         
%                 self.__fireStackRegisters(self.getAllStackRegisters())
%                 self.__fireScreenChangedEvent()
%                  
%             except Exception, e:
%                 self.__fireException(e.message)
% \end{verbatim}
